package com.aaa.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.aaa.dto.GetDjhUpdateDateTimeDto;
import com.aaa.enums.SyncNationReportEnum;
import com.aaa.properties.NationalReportProperty;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : luoBo
 */

@Slf4j
@Component
public class SyncNationReportServiceUtil {

    @Autowired
    private NationalReportProperty nationalReportProperty;

    @Getter
    private static SyncNationReportServiceUtil instance;

    public SyncNationReportServiceUtil(){
        instance = this;
    }
    //获取表的最大时间
    private static String getSyncTimeMax(SyncNationReportEnum syncNationReportEnum) {
        IService<Object> service = getServiceByEnum(syncNationReportEnum);
        // 创建 QueryWrapper
        QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("MAX(" + syncNationReportEnum.getMaxTimeName() + ") as syncTime");
        queryWrapper.last("LIMIT 1"); // 添加 LIMIT 1
        // 执行查询
        Object result = service.getOne(queryWrapper, false);
        return Objects.isNull(result)?null:result.toString();
    }

    /**
     * 根据枚举获取对应的service
     * @param syncNationReportEnum 定时任务的枚举
     * @return 返回的service
     */
    private static IService<Object> getServiceByEnum(SyncNationReportEnum syncNationReportEnum){
        return (IService<Object>) SpringUtil.getBean(syncNationReportEnum.getServiceClazz());
    }
    //需要新增的数据
    public static void processingData(SyncNationReportEnum syncNationReportEnum) {
        GetDjhUpdateDateTimeDto getDjhUpdateDateTimeDto = new GetDjhUpdateDateTimeDto();
        getDjhUpdateDateTimeDto.setUpdateTime(getSyncTimeMax(syncNationReportEnum));
        IService<Object> service;
        JSONObject jsonObject;
        try (HttpResponse response = HttpRequest.post(instance.nationalReportProperty.getIpPort() + syncNationReportEnum.getSyncNationReportUrl())
                .header("Content-Type", "application/json")
                .body(JSONUtil.toJsonStr(getDjhUpdateDateTimeDto))
                .execute()) {
            if (response.getStatus() != 200) {
                log.info("新增数据失败");
            }
            service = getServiceByEnum(syncNationReportEnum);
            jsonObject = new JSONObject(response.body());
        }
        List<Object> rangeList  = jsonObject.getJSONArray("result").toList(syncNationReportEnum.getEntityClazz());
        if (CollectionUtil.isNotEmpty(rangeList)){
            List<Object> localList = service.list();
            Map<Object, Object> dbListMap = localList.stream().collect(Collectors.toMap(obj -> ReflectUtil.getFieldValue(obj, syncNationReportEnum.getUniqueKeyName()), obj -> obj, (t1, t2) -> t1));
            List<Object> updateLocalList = rangeList.stream().filter(obj -> dbListMap.containsKey(ReflectUtil.getFieldValue(obj, syncNationReportEnum.getUniqueKeyName()))).collect(Collectors.toList());
            List<Object> insertLocalList = rangeList.stream().filter(obj -> !dbListMap.containsKey(ReflectUtil.getFieldValue(obj, syncNationReportEnum.getUniqueKeyName()))).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(insertLocalList)){
                service.saveBatch(insertLocalList);
                log.info("新增数据:{}{}", syncNationReportEnum.getSyncNationReportName(), insertLocalList.size());
            }
            if (CollectionUtil.isNotEmpty(updateLocalList)){
                service.updateBatchById(updateLocalList);
                log.info("修改数据:{}{}", syncNationReportEnum.getSyncNationReportName(), updateLocalList.size());
            }
        }
    }
}
